"""
天气查询API模块
@Author: Converted from PHP to Python
@Date: 2025-07-26
@Description: 提供城市天气查询功能，包括实时天气和未来天气预报
"""

from fastapi import APIRouter, HTTPException, Form
from pydantic import BaseModel
from typing import Optional, Dict, Any, List
import requests
import json
import mysql.connector
from datetime import datetime, date
import re
from ..core.config import settings

router = APIRouter()

# 数据模型
class WeatherResponse(BaseModel):
    """天气响应模型"""
    status: str
    message: str
    data: Optional[Dict[Any, Any]] = None

class RealtimeWeather(BaseModel):
    """实时天气数据模型"""
    temperature: str
    humidity: str
    info: str
    direct: str
    power: str
    aqi: str

class FutureWeather(BaseModel):
    """未来天气数据模型"""
    date: str
    temperature: str
    weather: str
    direct: str

class WeatherData(BaseModel):
    """天气数据模型"""
    city: str
    realtime: RealtimeWeather
    future: List[FutureWeather]

class WeatherRequest(BaseModel):
    """天气查询请求模型"""
    city: str

class WeatherService:
    """天气服务类"""
    
    def __init__(self):
        # 使用与日历模块相同的API密钥
        self.api_key = settings.juhe_api_key or "a1c370c490ec78ebfba7f49835383a9a"  # 备用密钥
        
        # 数据库配置
        self.db_config = {
            'host': settings.db_host,
            'user': settings.db_user,
            'password': settings.db_password,
            'database': settings.db_database,
            'charset': 'utf8mb4'
        }
    
    def get_database_connection(self):
        """获取数据库连接"""
        try:
            return mysql.connector.connect(**self.db_config)
        except mysql.connector.Error as e:
            raise HTTPException(status_code=500, detail=f"数据库连接失败: {str(e)}")
    
    def juhe_http_request(self, url: str, params: str, is_post: bool = False) -> Optional[str]:
        """
        聚合数据HTTP请求方法
        """
        try:
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'
            }
            
            if is_post:
                response = requests.post(url, data=params, headers=headers, timeout=12)
            else:
                response = requests.get(f"{url}?{params}", headers=headers, timeout=12)
            
            if response.status_code == 200:
                return response.text
            else:
                return None
                
        except requests.RequestException as e:
            print(f"请求异常: {str(e)}")
            return None
    
    def simple_weather(self, city: str) -> Dict[Any, Any]:
        """
        获取简单天气信息
        """
        # 清理城市名称（去掉"市"字）
        city = city.replace('市', '')
        
        if not city:
            raise HTTPException(status_code=400, detail="城市名称不能为空")
        
        conn = self.get_database_connection()
        cursor = conn.cursor(dictionary=True)
        
        try:
            # 先查询数据库是否有当天的数据
            today = date.today().strftime("%Y-%m-%d")
            cursor.execute(
                "SELECT realtime, future FROM weather WHERE city = %s AND dt LIKE %s",
                (city, f"{today}%")
            )
            existing_data = cursor.fetchone()
            
            if existing_data:
                # 返回缓存数据
                return {
                    'city': city,
                    'realtime': json.loads(existing_data['realtime']),
                    'future': json.loads(existing_data['future'])
                }
            
            # 如果数据库没有数据，则调用API
            api_url = 'http://apis.juhe.cn/simpleWeather/query'
            params = {
                'city': city,
                'key': self.api_key
            }
            params_string = '&'.join([f"{k}={v}" for k, v in params.items()])
            
            response = self.juhe_http_request(api_url, params_string, True)
            
            if not response:
                raise HTTPException(status_code=500, detail="API请求失败")
            
            result = json.loads(response)
            
            if not result:
                raise HTTPException(status_code=500, detail="API响应解析失败")
            
            error_code = result.get('error_code')
            if error_code != 0:
                raise HTTPException(
                    status_code=500, 
                    detail=f"API错误: {error_code}_{result.get('reason', '未知错误')}"
                )
            
            # 获取天气数据
            data = result['result']
            
            # 保存到数据库
            current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            insert_data = {
                'dt': current_datetime,
                'city': data['city'],
                'realtime': json.dumps(data['realtime'], ensure_ascii=False),
                'future': json.dumps(data['future'], ensure_ascii=False)
            }
            
            cursor.execute(
                "INSERT INTO weather (dt, city, realtime, future) VALUES (%(dt)s, %(city)s, %(realtime)s, %(future)s)",
                insert_data
            )
            conn.commit()
            
            return data
            
        except Exception as e:
            conn.rollback()
            if isinstance(e, HTTPException):
                raise
            raise HTTPException(status_code=500, detail=f"获取天气数据失败: {str(e)}")
        finally:
            cursor.close()
            conn.close()
    
    def get_weather_by_city(self, city: str) -> Dict[Any, Any]:
        """
        根据城市获取天气信息（主要接口方法）
        """
        try:
            # 获取天气数据
            weather_data = self.simple_weather(city)
            
            # 处理未来天气数据，将温度分隔符从"/"改为"-"
            future_weather = weather_data.get('future', [])
            for item in future_weather:
                if 'temperature' in item:
                    item['temperature'] = item['temperature'].replace('/', '-')
            
            weather_data['future'] = future_weather
            
            return weather_data
            
        except HTTPException:
            raise
        except Exception as e:
            raise HTTPException(status_code=500, detail=f"获取城市天气失败: {str(e)}")
    
    def get_weather_type(self, wid: int) -> Optional[str]:
        """
        根据天气ID获取天气类型（辅助方法）
        """
        conn = self.get_database_connection()
        cursor = conn.cursor(dictionary=True)
        
        try:
            cursor.execute("SELECT weather FROM type WHERE wid = %s", (wid,))
            result = cursor.fetchone()
            return result['weather'] if result else None
            
        except Exception as e:
            print(f"获取天气类型失败: {str(e)}")
            return None
        finally:
            cursor.close()
            conn.close()

# 创建服务实例
weather_service = WeatherService()

# API路由定义
@router.post("/api/weather", response_model=WeatherResponse)
async def get_weather(weather_request: WeatherRequest):
    """
    根据城市名称获取天气信息
    """
    try:
        weather_data = weather_service.get_weather_by_city(weather_request.city)
        
        return WeatherResponse(
            status="success",
            message=f"获取{weather_request.city}天气数据成功",
            data=weather_data
        )
    
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取天气失败: {str(e)}")

@router.post("/api/weather/form")
async def get_weather_form(city: str = Form(...)):
    """
    通过表单提交获取天气信息（兼容原PHP接口）
    """
    try:
        weather_data = weather_service.get_weather_by_city(city)
        
        return WeatherResponse(
            status="success",
            message=f"获取{city}天气数据成功",
            data=weather_data
        )
    
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取天气失败: {str(e)}")

@router.get("/api/weather/{city}", response_model=WeatherResponse)
async def get_weather_by_city_name(city: str):
    """
    通过URL路径参数获取城市天气
    """
    try:
        weather_data = weather_service.get_weather_by_city(city)
        
        return WeatherResponse(
            status="success",
            message=f"获取{city}天气数据成功",
            data=weather_data
        )
    
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取天气失败: {str(e)}")

@router.get("/api/weather/type/{wid}")
async def get_weather_type(wid: int):
    """
    根据天气ID获取天气类型
    """
    try:
        weather_type = weather_service.get_weather_type(wid)
        
        if weather_type is None:
            raise HTTPException(status_code=404, detail="天气类型不存在")
        
        return WeatherResponse(
            status="success",
            message="获取天气类型成功",
            data={"weather_type": weather_type}
        )
    
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取天气类型失败: {str(e)}")

@router.get("/api/weather/test")
async def test_weather():
    """
    测试天气API
    """
    try:
        # 测试获取北京天气
        test_city = "北京"
        weather_data = weather_service.simple_weather(test_city)
        
        return WeatherResponse(
            status="success",
            message="天气API测试成功",
            data={
                "test_city": test_city,
                "weather_data": weather_data,
                "endpoints": [
                    "POST /api/weather - JSON格式获取天气",
                    "POST /api/weather/form - 表单格式获取天气",
                    "GET /api/weather/{city} - URL参数获取天气",
                    "GET /api/weather/type/{wid} - 获取天气类型"
                ]
            }
        )
    
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"测试失败: {str(e)}")
